package com.apes.fico.masterdata.store.service;

import com.apes.fico.finance.model.costcollect.StoreTasks;
import com.apes.fico.finance.respository.StoreTasksRepository;
import com.apes.fico.masterdata.store.model.TypeStore;
import com.apes.fico.masterdata.store.repository.TypeStoreRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.outbox.OutboxPayloadWrapper;
import com.apes.framework.plugin.outbox.annotation.OutboxSubscriber;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apestech.framework.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.function.Consumer;

/**
 * @program: apes-server
 * @description:
 * @author: czs
 * @create: 2023-03-24 10:45
 **/
@Service("typeStoreService")
public class TypeStoreService extends DomainService {
    @Autowired
    StoreTasksRepository storeTasksRepository;
    @Autowired
    TypeStoreRepository typeStoreRepository;
    @Autowired
    EnumerationRepository enumerationRepository;

    @OutboxSubscriber(id="fico.typeStore.createOrUpdateTypeStore", name="门店经营任务更新类店")
    public void createOrUpdateTypeStore(OutboxPayloadWrapper wrapper) throws Exception {
        JSONObject jsonObject = JSONObject.toJSON(wrapper.getPayload());
        String id = jsonObject.getString("id");
        StoreTasks storeTasks = storeTasksRepository.findOne(id);
        createBusinessTypeStore(storeTasks);

        createGrossProfitTypeStore(storeTasks);

    }

    private void createBusinessTypeStore(StoreTasks storeTasks) {
        //查询历史数据
        List<TypeStore> typeStoreList = typeStoreRepository.findAll(JpaDsl.toCriteria(
                "dept", "EQ", storeTasks.getDept(),
                "tasksType", "EQ", "business",
                "yearMonth", "EQ", storeTasks.getYearMonth()
        ));
        //查询历史数据是否存在有效的类店
        TypeStore typeStore = typeStoreList.stream().filter(TypeStore::isValid).findFirst().orElse(new TypeStore());
        //如果存在有效的,并且金额不一样的则设置为无效,并且创建一个新的实体
        if (typeStore.getId()!=null&&storeTasks.getBusinessTasksAmt()!=typeStore.getTasksAmt()){
            typeStore.setValid(false);
            typeStoreRepository.saveAndFlush(typeStore);
            typeStore = new TypeStore();
        }
        //如果实体为空则创建
        //不为空即代表金额一致 则无需更改
        if (typeStore.getId()==null){
            typeStore.setDept(storeTasks.getDept());
            typeStore.setYearMonth(storeTasks.getYearMonth());
            typeStore.setTasksAmt(storeTasks.getBusinessTasksAmt());
            typeStore.setTasksType("business");
            typeStore.setValidDate(new Date());
            typeStore.setTypeStore(checkTypeDept(typeStore.getTasksAmt()));
            typeStoreRepository.saveAndFlush(typeStore);
        }
    }

    private void createGrossProfitTypeStore(StoreTasks storeTasks) {
        List<TypeStore> typeStoreList = typeStoreRepository.findAll(JpaDsl.toCriteria(
                "dept", "EQ", storeTasks.getDept(),
                "tasksType", "EQ", "grossProfit",
                "yearMonth", "EQ", storeTasks.getYearMonth()
        ));

        TypeStore typeStore = typeStoreList.stream().filter(TypeStore::isValid).findFirst().orElse(new TypeStore());

        if (typeStore.getId()!=null&&storeTasks.getGrossProfitTasksAmt()!=typeStore.getTasksAmt()){
            typeStore.setValid(false);
            typeStoreRepository.saveAndFlush(typeStore);
            typeStore = new TypeStore();
        }

        if (typeStore.getId()==null){
            typeStore.setDept(storeTasks.getDept());
            typeStore.setYearMonth(storeTasks.getYearMonth());
            typeStore.setTasksAmt(storeTasks.getGrossProfitTasksAmt());
            typeStore.setTasksType("grossProfit");
            typeStore.setValidDate(new Date());
            typeStore.setTypeStore(checkTypeDept(typeStore.getTasksAmt()));
            typeStoreRepository.saveAndFlush(typeStore);
        }
    }

    /**
     * 判断金额属于哪个档次
     * @param amt
     * @return
     */
    public Enumeration checkTypeDept(Double amt){
        Enumeration typeStore;
        if (amt<100000){
            typeStore = enumerationRepository.findByTypeAndCode("TypeStore", "D");
        }else if(amt<150000){
            typeStore = enumerationRepository.findByTypeAndCode("TypeStore", "C");
        }else if(amt<250000){
            typeStore = enumerationRepository.findByTypeAndCode("TypeStore", "B");
        }else {
            typeStore = enumerationRepository.findByTypeAndCode("TypeStore", "A");
        }
        return typeStore;
    }

    public void checkStoreTask(SimpleRequest request){

        checkNotExistsType("business",this::createBusinessTypeStore);
        checkNotExistsType("grossProfit",this::createGrossProfitTypeStore);
    }

    private void checkNotExistsType(String type, Consumer<StoreTasks> fun) {
        List<String> business;
        business = typeStoreRepository.findAllByNotExists(type);
        while (!business.isEmpty()){
            for (String s : business) {
                StoreTasks storeTasks = storeTasksRepository.findOne(s);
                fun.accept(storeTasks);
            }
            business = typeStoreRepository.findAllByNotExists(type);
        }
    }

    private Object synTypeStoreByApp(SimpleRequest request){
        Long time = 0L ;
        if (request.get("time") instanceof Integer){
            Integer integer = (Integer) request.get("time");
            time += integer;
        }else if (request.get("time") instanceof Long){
            time = request.get("time");
        }

        List<TypeStore> all = typeStoreRepository.findAll(JpaDsl.toCriteria(
                "lastUpdatedStamp", "GTE", new Date(time)
                ),new Sort(Sort.Direction.DESC, "lastUpdatedStamp"));
        return all;
    }

}
